package com.travelsky.client;

import java.awt.AWTException;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Image;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.lang.reflect.Method;
import java.util.Set;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

/**
 * 代码提交工具-主窗口
 ******************************************
 * @author HuangFeng  [2017年7月5日 上午11:45:08]
 * @version 1.0
 ******************************************
 */
public class Client_chatFrame extends JFrame implements ActionListener, KeyListener, ListSelectionListener {
	
	/**
	 * serialVersionUID
	 */
	private static final long serialVersionUID = 5590459786897968722L;
	
	/**
	 * 消息输入框
	 */
	private JTextField jtf_inputMess;
	
	/**
	 * 消息显示域
	 */
	private JTextArea jta_disMess;
	
	/**
	 * 发送消息按钮
	 */
	private JButton jbt_trans;
	
	/**
	 * 清楚聊天记录按钮
	 */
	private JButton jbt_clear;
	
	/**
	 * 退出按钮
	 */
	private JButton jbt_exit;
	
	/**
	 * 锁定/释放 令牌按钮
	 */
	private JButton jbt_lock;
	
	/**
	 * 等待/取消 令牌按钮
	 */
	private JButton jbt_wait;
	
	/**
	 * 令牌等待队列
	 */
	private JLabel jlb_queue;
	
	/**
	 * 集成状态
	 */
	private JLabel jlb_jenkins;
	
	/**
	 * sonar状态
	 */
	private JLabel jlb_sonar;
	
	/**
	 * 当前锁定人
	 */
	private JLabel jlb_lockUser;
	
	/**
	 * 在线用户列表
	 */
	private JList<Object> jlt_disUsers;
	
	/**
	 * 单人聊天按钮
	 */
	private JButton jbt_singlChat;
	
	/**
	 * scrollPane_1
	 */
	private JScrollPane scrollPane_1;
		
	/**
	 * 客户端对象
	 */
	private Client client;
	
	public String git_url="";
	public String sonar_url="";

	/**
	 * 构造函数
	 ******************************************
	 * @author HuangFeng [2017年7月5日 上午11:51:05]
	 * @version 1.0
	 ******************************************
	 * @param client 客户端对象
	 */
	public Client_chatFrame(Client client) {
		this.client = client;
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (UnsupportedLookAndFeelException e) {
			e.printStackTrace();
		}
		Image image = new ImageIcon(getClass().getResource("icon.jpg")).getImage();
		setIconImage(image);
		setTitle("代码提交工具"+client.version + "  " + client.groupName+"-"+client.username);
		setSize(450, 460);
		WinCenter.center(this);
		setResizable(false);
		//获得系统托盘的实例
		SystemTray systemTray = SystemTray.getSystemTray(); 
		TrayIcon trayIcon = null;
        try {
            trayIcon = new TrayIcon(image, "代码提交工具" + " " + client.groupName+"-"+client.username);
			systemTray.add(trayIcon);
			trayIcon.setImageAutoSize(true);
		} catch (AWTException e) {
			e.printStackTrace();
		} 
		this.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent arg0) {
				dispose(); //窗口最小化时dispose该窗口
			}
			//图标化窗口时调用事件
            public void windowIconified(WindowEvent e) {
                dispose(); //窗口最小化时dispose该窗口
            }
		});
		//双击托盘图标，软件正常显示
		trayIcon.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				// 双击托盘窗口再现
				if (e.getClickCount() == 1) {
					// 置此 frame 的状态。该状态表示为逐位掩码。
					setExtendedState(Frame.NORMAL); // 正常化状态
				}
				setVisible(true);
			}
		});
        getContentPane().setLayout(null);
        
		jlb_lockUser = new JLabel("当前锁定人:");
		jlb_lockUser.setFont(new Font("宋体", Font.PLAIN, 16));
		jlb_lockUser.setBounds(10, 10, 200, 32);
		getContentPane().add(jlb_lockUser);
		
		jbt_lock = new JButton("锁定令牌");
		jbt_lock.setFont(new Font("宋体", Font.PLAIN, 16));
		jbt_lock.setBounds(180, 10, 120, 32);
		jbt_lock.addActionListener(this);
		getContentPane().add(jbt_lock);
		
		jbt_wait = new JButton("等待令牌");
		jbt_wait.setFont(new Font("宋体", Font.PLAIN, 16));
		jbt_wait.setBounds(310, 10, 120, 32);
		jbt_wait.addActionListener(this);
		getContentPane().add(jbt_wait);
		
		jlb_queue = new JLabel("排队状态：");
		jlb_queue.setFont(new Font("宋体", Font.PLAIN, 16));
		jlb_queue.setForeground(Color.RED);
		jlb_queue.setBounds(10, 40, 500, 32);
		getContentPane().add(jlb_queue);
		
		jlb_jenkins = new JLabel("Git状态：");
		jlb_jenkins.setFont(new Font("宋体", Font.PLAIN, 16));
		jlb_jenkins.setForeground(Color.RED);
		jlb_jenkins.setBounds(10, 70, 500, 32);
		jlb_jenkins.addMouseListener(new MouseAdapter(){
			public void mouseClicked(MouseEvent e){
		    	  openURL(git_url);
		      }
		});
		getContentPane().add(jlb_jenkins);
		
		jlb_sonar = new JLabel("Sonar：");
		jlb_sonar.setFont(new Font("宋体", Font.PLAIN, 16));
		jlb_sonar.setForeground(Color.RED);
		jlb_sonar.setBounds(10, 100, 500, 32);
		jlb_sonar.addMouseListener(new MouseAdapter(){
			public void mouseClicked(MouseEvent e){
		    	  openURL(sonar_url);
		      }
		});
		getContentPane().add(jlb_sonar);
		
		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setBorder(BorderFactory.createTitledBorder("聊天记录"));
		scrollPane.setBounds(10, 140, 283, 167);
		scrollPane.setWheelScrollingEnabled(true);
		getContentPane().add(scrollPane);

		jta_disMess = new JTextArea();
		jta_disMess.setEditable(false);
		scrollPane.setViewportView(jta_disMess);

		jtf_inputMess = new JTextField();
		jtf_inputMess.addKeyListener(this);
		jtf_inputMess.setBounds(10, 371, 192, 32);
		getContentPane().add(jtf_inputMess);
		jtf_inputMess.setColumns(10);

		jbt_trans = new JButton("发  送");
		jbt_trans.setFont(new Font("宋体", Font.PLAIN, 14));
		jbt_trans.setBounds(212, 371, 93, 32);
		jbt_trans.addActionListener(this);
		getContentPane().add(jbt_trans);

		jbt_clear = new JButton("清除聊天记录");
		jbt_clear.setFont(new Font("宋体", Font.PLAIN, 14));
		jbt_clear.setBounds(158, 317, 135, 37);
		jbt_clear.addActionListener(this);
		getContentPane().add(jbt_clear);

		jbt_exit = new JButton("退出");
		jbt_exit.setFont(new Font("宋体", Font.PLAIN, 14));
		jbt_exit.setBounds(20, 319, 128, 37);
		jbt_exit.addActionListener(this);
		getContentPane().add(jbt_exit);

		scrollPane_1 = new JScrollPane();
		scrollPane_1.setBorder(BorderFactory.createTitledBorder("在线用户"));
		scrollPane_1.setBounds(303, 140, 128, 214);
		getContentPane().add(scrollPane_1);

		jlt_disUsers = new JList<Object>();
		jlt_disUsers.setVisibleRowCount(4);
		jlt_disUsers.setSelectedIndex(0);
		jlt_disUsers.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
		jlt_disUsers.addListSelectionListener(this);
		scrollPane_1.setViewportView(jlt_disUsers);

		jbt_singlChat = new JButton("单人聊天");
		jbt_singlChat.setBounds(315, 371, 116, 32);
		jbt_singlChat.addActionListener(this);
		getContentPane().add(jbt_singlChat);
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == jbt_clear) {
			jta_disMess.setText("");
		}else if (e.getSource() == jbt_trans) {
			String mess = jtf_inputMess.getText();
			mess.trim();
			if (mess.equals("")) {
				JOptionPane.showMessageDialog(this, "不能发送空消息");
			} else {
				client.transMess(mess);
			}
			jtf_inputMess.setText("");
		}else if (e.getSource() == jbt_exit) {
			if (JOptionPane.OK_OPTION == JOptionPane.showConfirmDialog(this, "是否确定要退出？", "提示",
					JOptionPane.OK_CANCEL_OPTION)) {
				this.setVisible(false);
				if(jbt_wait.getText().equals("取消等待")){
					client.waitToken(jbt_wait.getText());
				}
				client.exitChat();
				System.exit(0);
			}
		}else if (e.getSource() == jbt_singlChat) {
			String user_names = (String) jlt_disUsers.getSelectedValue();
			if (user_names == null) {
				JOptionPane.showMessageDialog(this, "您未选择聊天对象\n请选择要单独聊天的对象");
			} else if (user_names.equals(client.username)) {
				JOptionPane.showMessageDialog(this, "你想跟自己聊天么，这样很无聊诶");
			} else if (!client.getC_singleFrames().containsKey(user_names)) {
				createSingleChatFrame(user_names);
			} else {
				client.getC_singleFrames().get(user_names).setFocusableWindowState(true);
			}
		}else if (e.getSource() == jbt_lock){
			if(jbt_lock.getText().equals("锁定令牌")){
				client.lockToken();
			}else{
				client.releaseToken();
			}
		}else if(e.getSource() == jbt_wait){
			client.waitToken(jbt_wait.getText());
		}
	}

	/**
	 * 回车键
	 */
	@Override
	public void keyPressed(KeyEvent arg0) {
		if (arg0.getKeyCode() == KeyEvent.VK_ENTER) {
			if (arg0.getSource() == jtf_inputMess) {
				jbt_trans.doClick();
			}
		}
	}
	
	@Override
	public void valueChanged(ListSelectionEvent e) {
	}

	@Override
	public void keyReleased(KeyEvent arg0) {
	}

	@Override
	public void keyTyped(KeyEvent arg0) {
	}

	/**
	 * 显示聊天信息
	 ******************************************
	 * @author HuangFeng [2017年7月5日 上午11:58:47]
	 * @version 1.0
	 ******************************************
	 * @param substring 消息
	 */
	public void setDisMess(String substring) {
		int local = substring.indexOf("@chat");
		String message = substring.substring(0, local);
		jta_disMess.append( message + "\n");
		jta_disMess.setCaretPosition(jta_disMess.getText().length());
		//如果包含@自己名字
		if (message.contains("@"+client.username)) {
			//把窗口置为正常化状态
			setExtendedState(Frame.NORMAL);
			setVisible(true);
		}
	}

	/**
	 * 设置在线用户列表
	 ******************************************
	 * @author HuangFeng [2017年7月5日 下午12:20:37]
	 * @version 1.0
	 ******************************************
	 * @param chat_re 消息
	 */
	public void setDisUsers(String chat_re) {
		String[] infos = chat_re.split("@userlist");
		String[] info = new String[infos.length / 2];
		int i = 0;
		client.username_online.clear();
		client.clientuserid.clear();
		for(i=0;i<infos.length;i++){
			client.username_online.add(0, infos[i]);
			client.clientuserid.add(0,Integer.parseInt(infos[++i]));
		}
		if (!client.c_singleFrames.isEmpty()) {
			Set<String> set = client.c_singleFrames.keySet();
			for (String string : set) {
				if(!client.username_online.contains(string)){
					client.c_singleFrames.get(string).setExitNotify();
				}
			}
		}
		for (i = 0; i < client.username_online.size(); i++) {
			info[i] = client.username_online.get(i);
		}
		jlt_disUsers.removeAll();
		jlt_disUsers.setListData(info);
	}
	
	/**
	 * 关闭客户端
	 ******************************************
	 * @author HuangFeng [2017年7月5日 下午12:31:19]
	 * @version 1.0
	 ******************************************
	 * @param message 消息
	 */
	public void closeClient(String message) {
		JOptionPane.showMessageDialog(this, message , "提示", JOptionPane.OK_OPTION);
		setVisible(false);
		client.exitClient();
	}

	/**
	 * 创建单人聊天窗口
	 ******************************************
	 * @author HuangFeng [2017年7月5日 下午12:32:10]
	 * @version 1.0
	 ******************************************
	 * @param name 用户名
	 */
	public void createSingleChatFrame(String name) {
		Client_singleFrame c_singlFrame = new Client_singleFrame(client, name);
		client.getC_singleFrames().put(name, c_singlFrame);
		try {
			c_singlFrame.setUserThreadID(client.getClientuserid().get(client.getUsername_online().indexOf(name)));
		} catch (Exception e) {
		}
		c_singlFrame.setVisible(true);
	}

	/**
	 * 设置单人聊天窗口
	 ******************************************
	 * @author HuangFeng [2017年7月5日 下午12:32:43]
	 * @version 1.0
	 ******************************************
	 * @param chat_re 消息
	 */
	public void setSingleFrame(String chat_re) {
		String[] infos = chat_re.split("@single");
		try {
			if (client.getC_singleFrames().containsKey(infos[0])) {
				client.getC_singleFrames().get(infos[0]).setDisMess(infos[3]);
			} else {
				createSingleChatFrame(infos[0]);
				client.getC_singleFrames().get(infos[0]).setDisMess(infos[3]);
			}
		} catch (Exception e) {
		}
	}

	/**
	 * 更新锁定或释放按钮状态
	 ******************************************
	 * @author HuangFeng [2017年7月5日 下午12:33:16]
	 * @version 1.0
	 ******************************************
	 * @param lockTokenUser 当前锁定人
	 */
	public void setLockOrRealse(String lockTokenUser) {
		client.setLockTokenUser(lockTokenUser);
		jbt_wait.setEnabled(false);
		//当前没有人锁定
		if(lockTokenUser.trim().equals("0") ){
			//等待队列的第一个人就是自己
			if(client.getFirstWaitUser().equals(client.getUsername())){
				client.waitToken("取消等待");//取消排队
				client.lockToken();//锁定令牌
				setExtendedState(Frame.NORMAL); // 正常化状态
				setVisible(true);
			}else{
				jlb_lockUser.setText("当前锁定人：无");
				jbt_lock.setText("锁定令牌");
				jbt_lock.setEnabled(true);
			}
		//当前锁定人是自己
		}else if(lockTokenUser.trim().equals(client.getUsername())){
			jlb_lockUser.setText("当前锁定人：" + lockTokenUser);
			jbt_lock.setText("释放令牌");
			jbt_lock.setEnabled(true);
			//如果Git最后提交人是自己，且提交号不等于锁定之前的提交号
			if(client.getGitLastUpdateUser().equals(lockTokenUser)
					&&!client.getGitId().equals(client.getGitLockId())){
				//如果Git状态为成功
				if(client.getGitStatus().equals("success")){
					//自动释放令牌
					client.releaseToken();
				}else if(client.getGitStatus().equals("failed")){
					//把窗口置为正常化状态，提醒失败了
					setExtendedState(Frame.NORMAL);
					setVisible(true);
				}
			}
		//当前锁定人是别人
		}else{
			jlb_lockUser.setText("当前锁定人：" + lockTokenUser);
			jbt_wait.setEnabled(true);
			jbt_lock.setText("锁定令牌");
			jbt_lock.setEnabled(false);
		}
	}

	/**更新Git状态
	 ******************************************
	 * @author HuangFeng [2017年7月3日 下午3:31:38]
	 * @version 1.0
	 ******************************************
	 * @param chat_re 消息
	 */
	public void updateGitAndSonarStatus(String chat_re) {
		String[] info = chat_re.split("@Git");
		client.setGitStatus(info[0].split("-")[1]);
		client.setGitId(info[0].split("-")[0].split(":")[0]);
		client.setGitLastUpdateUser(info[0].split("-")[0].split(":")[1]);
		StringBuffer text = new StringBuffer();
		text.append("Git状态：");
		int i = 0;
		for(i=0;i<info.length-1;i++){
			text.append(info[i]);
		}
		jlb_jenkins.setText(new String(text));
		setLockOrRealse(client.getLockTokenUser());
		
		StringBuffer sonarText = new StringBuffer();
		sonarText.append("Sonar：");
		String[] sonar = chat_re.split("@Git@Sonar")[1].split("@Sonar");
		for (String string : sonar) {
			String[] status = string.split(":");
			if(status[0].equals("BLOCKER")){
				sonarText.append("阻断:"+status[1]);
			}
			else if(status[0].equals("CRITICAL")){
				sonarText.append(" 严重:"+status[1]);
			}
		}
		String coverage = chat_re.split("@Sonar@Coverage")[1];
		sonarText.append(coverage);
		jlb_sonar.setText(new String(sonarText));
	}
	
	/**更新等待令牌的队列
	 ******************************************
	 * @author HuangFeng [2017年7月4日 下午6:44:25]
	 * @version 1.0
	 ******************************************
	 * @param chat_re 消息
	 */
	public void updateQueue(String chat_re) {
		String[] info = chat_re.split(",");
		if(info.length>1){
			client.setFirstWaitUser(info[0]);
		}else{
			client.setFirstWaitUser("");
		}
		StringBuffer text = new StringBuffer();
		text.append("排队状态：");
		int i = 0;
		for (i=0;i<info.length-1;i++) {
			text.append(i+1+":"+info[i]+" ");
		}
		jlb_queue.setText(new String(text));
		if(chat_re.contains(client.username)){
			jbt_wait.setText("取消等待");
		}else{
			jbt_wait.setText("等待令牌");
		}
	}

	/**同名用户登录，强制下线
	 ******************************************
	 * @author HuangFeng [2017年7月6日 下午3:01:18]
	 * @version 1.0
	 ******************************************
	 * @param chat_re 消息
	 */
	public void forceQuit(String chat_re) {
		String[] info = chat_re.split("@forceQuit");
		if (client.getThreadID() == Integer.parseInt(info[0])) {
			JOptionPane.showMessageDialog(this, "由于有同名的用户登录，所以您被强制下线了 ^··^");
			client.exitClient();
		}
	}
  
	/**
	 * 打开浏览器
	 ******************************************
	 * @author HuangFeng [2017年8月23日 下午6:27:46]
	 * @version 1.0
	 ******************************************
	 * @param url 链接
	 * @throws Exception 异常
	 */
	public void openURL(String url){
		try {
			// 获取操作系统的名字
			String osName = System.getProperty("os.name", "");
			if (osName.startsWith("Mac OS")) {
				// 苹果的打开方式
				Class<?> fileMgr = Class.forName("com.apple.eio.FileManager");
				Method openURL = fileMgr.getDeclaredMethod("openURL", new Class[] { String.class });
				openURL.invoke(null, new Object[] { url });
			} else if (osName.startsWith("Windows")) {
				// windows的打开方式。
				Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + url);
			} else {
				// Unix or linux的打开方式
				String[] browsers = { "firefox", "opera", "konqueror", "epiphany", "mozilla", "netscape" };
				String browser = null;
				for (int count = 0; count < browsers.length && browser == null; count++){
					// 执行代码，在brower有值后跳出，
					// 这里是如果进程创建成功了，==0是表示正常结束。
					if (Runtime.getRuntime().exec(new String[] { "which", browsers[count] }).waitFor() == 0){
						browser = browsers[count];
					}
				}
				if (browser == null)
					throw new Exception("Could not find web browser");
				else{
					// 这个值在上面已经成功的得到了一个进程。
					Runtime.getRuntime().exec(new String[] { browser, url });
				}
			}
		} catch (Exception e) {
			JOptionPane.showMessageDialog(this, "打开浏览器失败");
		}
	}
	
	/**
	 * 执行定时任务
	 ******************************************
	 * @author HuangFeng [2017年10月13日 下午1:02:18]
	 * @version 1.0
	 ******************************************
	 * @param chat_re 消息
	 */
	public void timeTask(String chat_re) {
		String[] info = chat_re.split("@timeTask");
		//把窗口置为正常化状态
		setExtendedState(Frame.NORMAL);
		setVisible(true);
		JOptionPane.showMessageDialog(this, info[1]);
	}

}
